﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Emerson.Storage.Service.Interface;
using Emerson.Storage.Entities;
using System.Data.Objects;
using System.Data;
using System.Runtime.Remoting.Channels.Tcp;
using System.Runtime.Remoting.Channels;
using Emerson.Storage.Agent.Core;
using System.Runtime.Remoting;
using System.Configuration;
using System.Net;

namespace Emerson.Storage.Service
{
    public class WorkstationService
    {
        public WorkstationRoot GetWorkstationRoot()
        {

            using (SmartStorageEntities sse = new SmartStorageEntities())
            {
                WorkstationRoot root = new WorkstationRoot();
                root.Name = sse.DefaultContainerName;
                var selectedGroups = sse.Group;
                foreach (var g in selectedGroups)
                {
                    g.Workstation.Load();
                    foreach (var w in g.Workstation)
                    {
                        w.Battery.Load();
                    }
                }

                root.Groups = selectedGroups.ToList();

                return root;
            }
        }

        public void AddGroup(Group newGroup)
        {
            using (SmartStorageEntities sse = new SmartStorageEntities())
            {
                sse.AddToGroup(newGroup);

                try
                {
                    sse.SaveChanges();
                }
                catch (UpdateException ue)
                {
                    if (ue.InnerException != null)
                        throw new UpdateException(ue.InnerException.Message, ue.InnerException);
                }
            }
        }

        public void DeleteGroup(int groupId)
        {
            using (SmartStorageEntities sse = new SmartStorageEntities())
            {
                var groups = from g in sse.Group
                             where g.GroupId == groupId
                             select g;

                if (groups.Count() == 0)
                    throw new Exception("Cannot find the specified group, maybe it is already deleted");

                Group curGroup = groups.First();
                sse.Attach(curGroup);
                sse.DeleteObject(curGroup);
                sse.SaveChanges();
            }
        }

        internal Workstation FindWorkstation(string address)
        {
            IAgentService agentService = AgentAccess.GetAgentService(address);

            WorkstationInfo wi = agentService.GetWorkstationInfo();
            Workstation workstation = wi.ConvertToWorkstation();
            return workstation;
        }

        internal void AddWorkstation(int groupId, Workstation newWorkstation)
        {
            //set the containing batteries
            IAgentService agentService = AgentAccess.GetAgentService(newWorkstation.IPAddress);
            List<BatteryInfo> batteryInfos = agentService.GetBatteryInfos();
            foreach (var bi in batteryInfos)
            {
                Battery bat = bi.ConvertToBattery();
                bat.LogTime = DateTime.Now;
                newWorkstation.Battery.Add(bat);
            }
            
            using (SmartStorageEntities sse = new SmartStorageEntities())
            {
                //set the parent group
                var groups = from g in sse.Group
                             where g.GroupId == groupId
                             select g;
                if (groups.Count() == 0)
                    throw new EntityNotFoundException("Group", groupId);
                Group parentGroup = groups.First();

                parentGroup.Workstation.Add(newWorkstation);
                try
                {
                    sse.SaveChanges();
                }
                catch (UpdateException ue)
                {
                    if (ue.InnerException != null)
                        throw new UpdateException(ue.InnerException.Message, ue.InnerException);
                }
            }
        }

        internal Workstation GetWorkstation(int workstationId)
        {
            using (SmartStorageEntities sse = new SmartStorageEntities())
            {
                var workstations = from w in sse.Workstation
                                   where w.WorkstationId == workstationId
                                   select w;
                if (workstations.Count() == 0)
                    throw new EntityNotFoundException("Workstation", workstationId);
                Workstation wk = workstations.First();
                return wk;
            }
        }

        internal void DeleteWorkstation(int workstationid)
        {
            using (SmartStorageEntities sse = new SmartStorageEntities())
            {
                var wks = from w in sse.Workstation
                          where w.WorkstationId == workstationid
                          select w;

                if (wks.Count() == 0)
                    throw new EntityNotFoundException("Workstation", workstationid);

                Workstation curWorkstation = wks.First();

                sse.Attach(curWorkstation);
                sse.DeleteObject(curWorkstation);
                sse.SaveChanges();
            }
        }

        internal Battery GetBattery(int deviceId)
        {
            using (SmartStorageEntities sse = new SmartStorageEntities())
            {
                var bats = from b in sse.Battery
                           where b.BatteryId == deviceId
                           select b;
                if (bats.Count() == 0)
                    throw new EntityNotFoundException("Workstation", deviceId);
                Battery bat = bats.First();
                return bat;
            }
        }

        internal void DeleteBattery(int deviceId)
        {
            using (SmartStorageEntities sse = new SmartStorageEntities())
            {
                var bats = from b in sse.Battery
                           where b.BatteryId == deviceId
                           select b;
                if (bats.Count() == 0)
                    throw new EntityNotFoundException("Battery", deviceId);

                Battery curBattery = bats.First();

                sse.Attach(curBattery);
                sse.DeleteObject(curBattery);
                sse.SaveChanges();
            }
        }

        internal Group GetGroup(int groupId)
        {
            using (SmartStorageEntities sse = new SmartStorageEntities())
            {
                var groups = from g in sse.Group
                             where g.GroupId == groupId
                             select g;
                if (groups.Count() == 0)
                    throw new EntityNotFoundException("Group", groupId);

                Group curGroup = groups.First();
                curGroup.Workstation.Load();
                return curGroup;
            }
        }
    }
}
